import sys
import pandas as pd
from PyQt6.uic.load_ui import loadUi

class QuizApp:
    def __init__(self):
        """
        初始化。
        """
        from PyQt6.QtWidgets import (QMainWindow, QPushButton, QTextEdit)
        from PyQt6.QtGui import QAction, QShortcut, QKeySequence

        self.df: pd.DataFrame = None  # 题库数据
        self.current_question_index = 0  # 题目索引列
        # 初始化统计数据存储
        self.question_status = {}  # 用字典存储每道题的最新状态

        # ui初始化
        self.ui: QMainWindow = loadUi('./main.ui')
        self.question_label: QTextEdit = self.ui.question_label # 题目显示
        # 打开题库文件
        action_open: QAction = self.ui.action_open
        action_open.triggered.connect(self.open_file_dialog)
        # 打开题库统计信息
        action_table: QAction = self.ui.action_table
        action_table.triggered.connect(self.show_statistics_table)
        # 选项组 - 修改为支持多选
        self.option_buttons = [
            self.ui.radio_A,
            self.ui.radio_B,
            self.ui.radio_C,
            self.ui.radio_D
        ]
        # 为每个选项按钮添加快捷键
        self.option_shortcuts = []
        for i, button in enumerate(self.option_buttons):
            key = chr(ord('1') + i)  # A, B, C, D
            shortcut = QShortcut(QKeySequence(key), self.ui)
            shortcut.activated.connect(lambda b=button: self.toggle_option(b))
            self.option_shortcuts.append(shortcut)
        # 提交按钮
        self.submit_button: QPushButton = self.ui.submit_button
        self.submit_button.clicked.connect(self.check_answer)
        # 上一题按钮
        self.prev_button: QPushButton = self.ui.prev_button
        self.prev_button.clicked.connect(self.load_prev_question)
        # 下一题按钮
        self.next_button: QPushButton = self.ui.next_button
        self.next_button.clicked.connect(self.load_next_question)
        self.next_button.setFocus()  # 确保焦点在明确的控件上
        # 添加跳转按钮
        jump_button: QPushButton = self.ui.jump_button
        jump_button.clicked.connect(self.jump_to_question)
        # 添加反馈文本框
        self.feedback_label: QTextEdit = self.ui.feedback_label
        # 添加回车键提交答案的快捷键
        enter_shortcut = QShortcut(QKeySequence("Return"), self.ui)
        enter_shortcut.activated.connect(self.check_answer)
        # 添加左箭头键切换上一题的快捷键
        prev_shortcut = QShortcut(QKeySequence("Left"), self.ui)
        prev_shortcut.activated.connect(self.load_prev_question)
        # 添加右箭头键切换下一题的快捷键
        next_shortcut = QShortcut(QKeySequence("Right"), self.ui)
        next_shortcut.activated.connect(self.load_next_question)

    def show_statistics_table(self):
        """
        显示统计表格。
        """
        from PyQt6.QtCore import Qt
        from PyQt6.QtWidgets import QDialog, QTableWidget, QTableWidgetItem

        if self.df is None:
            return  # 未打开题库文件。
        # 重新初始化统计表格以适应新的题目数量
        statistics_window: QDialog = loadUi('./table.ui')
        stats_table: QTableWidget = statistics_window.stats_table
        stats_table.setRowCount(self.df.shape[0])  # 设置表格行数
        
        for question_num, status in self.question_status.items():
            if question_num < stats_table.rowCount():
                # 题号
                item = QTableWidgetItem()
                item.setData(Qt.ItemDataRole.DisplayRole, question_num)
                item.setTextAlignment(Qt.AlignmentFlag.AlignCenter)
                stats_table.setItem(question_num, 0, item)
                # 类别
                item = QTableWidgetItem(status["class"])
                item.setTextAlignment(Qt.AlignmentFlag.AlignCenter)
                stats_table.setItem(question_num, 1, item)
                # 答题状态
                item = QTableWidgetItem("正确" if status["is_correct"] else "错误")
                item.setTextAlignment(Qt.AlignmentFlag.AlignCenter)
                item.setForeground(Qt.GlobalColor.green if status["is_correct"] else Qt.GlobalColor.red)
                stats_table.setItem(question_num, 2, item)
                # 题库答案
                item = QTableWidgetItem(status["correct_answer"])
                stats_table.setItem(question_num, 3, item)
                # 用户答案
                user_answer = status["user_answer"]
                item = QTableWidgetItem(user_answer)
                stats_table.setItem(question_num, 4, item)
        stats_table.resizeColumnsToContents()  # 自动调整列、宽
        statistics_window.exec()  # 创建表格页面

    def load_question(self):
        """
        加载题库。
        """
        question_data = self.df.iloc[self.current_question_index]
        self.question_label.setText(f'【题号】{self.current_question_index}\n' 
                                    + f'【类型】{question_data["class"]}\n'
                                    + f'{question_data["content"]}')
        # 设置选项
        options = [
            question_data["A"],
            question_data["B"],
            question_data["C"],
            question_data["D"]
        ]
        # 清除上一题的选择
        for i, button in enumerate(self.option_buttons):
            button.setText(str(options[i]))
            button.setChecked(False)
        self.feedback_label.setText("")  # 清除反馈信息
        if question_data["class"] == "填空题":
            self.feedback_label.setPlaceholderText("填空题在此答题")
        else:
            self.feedback_label.setPlaceholderText("")
        self.feedback_label.setStyleSheet("background-color: #F5F7FA; border: 1px solid #BDC3C7; color: #2C3E50;")
        # 根据题目位置启用/禁用导航按钮
        self.prev_button.setEnabled(self.current_question_index > 0)
        self.next_button.setEnabled(self.current_question_index < self.df.shape[0] - 1)

    def load_prev_question(self):
        """
        加载上一题。
        """
        if self.df is None:
            return  # 未打开题库。
        if self.current_question_index > 0:
            self.current_question_index -= 1
            self.load_question()
        else:
            self.feedback_label.setText("已经是第一题！")

    def load_next_question(self):
        """
        加载下一题。
        """
        if self.df is None:
            return  # 未打开题库。
        if self.current_question_index < self.df.shape[0] - 1:
            self.current_question_index += 1
            self.load_question()
        else:
            self.feedback_label.setText("已经是最后一题！")

    def toggle_option(self, button):
        """
        切换选项的选择状态。
        :param button: QPushButton对象。
        """
        button.setChecked(not button.isChecked())

    def check_answer(self):
        """
        比较提交答案和题库答案。
        """
        if self.df is None:
            return  # 未打开题库文件。
        
        question_data = self.df.iloc[self.current_question_index]
        # 统计题库的答案
        correct_answers = str(question_data["answer"])
        if question_data["class"] == "填空题":
            selected_answers = self.feedback_label.toPlainText()
        else:
            # 统计用户选择的答案
            selected_answers = []
            for button in self.option_buttons:
                if button.isChecked():
                    selected_answers.append(chr(self.option_buttons.index(button) + ord('A')))
            selected_answers = "".join(selected_answers)

        is_correct = (selected_answers == correct_answers)  # 比较题库答案和用户答案
        # 更新最新状态到字典
        self.question_status[self.current_question_index] = {
            "is_correct": is_correct,
            "class": question_data["class"],
            "correct_answer": correct_answers,
            "user_answer": selected_answers
        }
        if is_correct:
            self.feedback_label.setText("回答正确！")
            self.feedback_label.setStyleSheet("background-color: #d4edda; border: 1px solid #c3e6cb; color: #155724;")
        else:
            self.feedback_label.setText(f"回答错误！正确答案是：\n{correct_answers}")
            self.feedback_label.setStyleSheet("background-color: #f8d7da; border: 1px solid #f5c6cb; color: #721c24;")
        
        self.feedback_label.style().unpolish(self.feedback_label)
        self.feedback_label.style().polish(self.feedback_label)

    def jump_to_question(self):
        """
        跳转到指定题号。
        """
        from PyQt6.QtWidgets import QInputDialog
        if self.df is None:
            return
        max_index = self.df.shape[0] - 1
        current_index = self.current_question_index  # 转换为显示用的题号(从0开始)
        # 获取用户输入
        text, ok = QInputDialog.getInt(
            self.ui, "跳转到题号", f"请输入题号 (0-{max_index}):",
            current_index, min=0, max=max_index
        )
        if ok:
            if 0 <= text < self.df.shape[0]:
                self.current_question_index = text
                self.load_question()
            else:
                self.feedback_label.setText(f"无效的题号，请输入0-{max_index}之间的数字")

    def open_file_dialog(self):
        """
        打开文件对话框选择题库文件。
        """
        from PyQt6.QtWidgets import QFileDialog
        file_path, _ = QFileDialog.getOpenFileName(
            self.ui, caption="选择题库文件", directory='./',
            filter="Excel Files (*.xlsx *.xls)"
        )
        if file_path:
            self.df = pd.read_excel(file_path)
            self.current_question_index = 0
            self.question_status.clear()  # 清空统计数据存储
            self.load_question()  # 加载第一题

if __name__ == "__main__":
    from PyQt6.QtWidgets import QApplication
    app = QApplication(sys.argv)
    quiz_app = QuizApp()
    quiz_app.ui.show()
    sys.exit(app.exec())